How to add multiple named parameters to the SQL statement? - ibatis

I would like to write something like this in myBatis (using anotations instead of XML):
#Insert("INSERT INTO friendships (user_id, friend_id) VALUES (#{user.id}, {friend.id})")
public void insert(User user, User friend);
Is this possible? How exactly?
(Note, I would like to use Objects of type User for type-safty. I know that using int parameters and use #{1} and #{2} as placeholders would work)

You can use annotations to provide a namespace for multiple input parameters. These essentially give nice names to the #{1.foo} and #{2.bar} identifiers.
#Insert("INSERT INTO friendships (user_id, friend_id) VALUES (#{user.id},
#{friend.id})")
public void insert(#Param(value="user") User user, #Param(value="friend") User friend)

It seems like this is not possible, so I created a wrapper class:
class Friendship {
private final User user;
private final User friend;
public Friendship(User user, User friend) {
this.user = user;
this.friend = friend;
}
public int getUserId(){
return user.getId();
}
public int getFriendId(){
return friend.getId();
}
}
And changed the Mapper to this:
#Insert("INSERT INTO friendships (user_id, friend_id) VALUES (#{userId}, #{friendId})")
public void insert(Friendship friendship);

Related

Populating a table from a file only last column is populated JavaFX [duplicate]

This has baffled me for a while now and I cannot seem to get the grasp of it. I'm using Cell Value Factory to populate a simple one column table and it does not populate in the table.
It does and I click the rows that are populated but I do not see any values in them- in this case String values. [I just edited this to make it clearer]
I have a different project under which it works under the same kind of data model. What am I doing wrong?
Here's the code. The commented code at the end seems to work though. I've checked to see if the usual mistakes- creating a new column instance or a new tableview instance, are there. Nothing. Please help!
//Simple Data Model
Stock.java
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getstockTicker() {
return stockTicker.get();
}
public void setstockTicker(String stockticker) {
stockTicker.set(stockticker);
}
}
//Controller class
MainGuiController.java
private ObservableList<Stock> data;
#FXML
private TableView<Stock> stockTableView;// = new TableView<>(data);
#FXML
private TableColumn<Stock, String> tickerCol;
private void setTickersToCol() {
try {
Statement stmt = conn.createStatement();//conn is defined and works
ResultSet rsltset = stmt.executeQuery("SELECT ticker FROM tickerlist order by ticker");
data = FXCollections.observableArrayList();
Stock stockInstance;
while (rsltset.next()) {
stockInstance = new Stock(rsltset.getString(1).toUpperCase());
data.add(stockInstance);
}
} catch (SQLException ex) {
Logger.getLogger(WriteToFile.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Connection Failed! Check output console");
}
tickerCol.setCellValueFactory(new PropertyValueFactory<Stock,String>("stockTicker"));
stockTableView.setItems(data);
}
/*THIS, ON THE OTHER HAND, WORKS*/
/*Callback<CellDataFeatures<Stock, String>, ObservableValue<String>> cellDataFeat =
new Callback<CellDataFeatures<Stock, String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(CellDataFeatures<Stock, String> p) {
return new SimpleStringProperty(p.getValue().getstockTicker());
}
};*/
Suggested solution (use a Lambda, not a PropertyValueFactory)
Instead of:
aColumn.setCellValueFactory(new PropertyValueFactory<Appointment,LocalDate>("date"));
Write:
aColumn.setCellValueFactory(cellData -> cellData.getValue().dateProperty());
For more information, see this answer:
Java: setCellValuefactory; Lambda vs. PropertyValueFactory; advantages/disadvantages
Solution using PropertyValueFactory
The lambda solution outlined above is preferred, but if you wish to use PropertyValueFactory, this alternate solution provides information on that.
How to Fix It
The case of your getter and setter methods are wrong.
getstockTicker should be getStockTicker
setstockTicker should be setStockTicker
Some Background Information
Your PropertyValueFactory remains the same with:
new PropertyValueFactory<Stock,String>("stockTicker")
The naming convention will seem more obvious when you also add a property accessor to your Stock class:
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getStockTicker() {
return stockTicker.get();
}
public void setStockTicker(String stockticker) {
stockTicker.set(stockticker);
}
public StringProperty stockTickerProperty() {
return stockTicker;
}
}
The PropertyValueFactory uses reflection to find the relevant accessors (these should be public). First, it will try to use the stockTickerProperty accessor and, if that is not present fall back to getters and setters. Providing a property accessor is recommended as then you will automatically enable your table to observe the property in the underlying model, dynamically updating its data as the underlying model changes.
put the Getter and Setter method in you data class for all the elements.

SQLite Xamarin PCL

I am developing an App in Xamarin type PCL, for my DB structure, I want to use SQLite, but I have the following doubts ...
When entering a record in my DB, it takes the ID = 0, in my data model use
[PrimaryKey, AutoIncrement]
Public int ViolationID {get; set; }
And still, I enter the registry at zero, I do not know I'm doing wrong ... or is this a bug in the SQLite.NET-PCL package?
How can I verify that these records are actually being entered? I have in my code
public class DataAccess : IDisposable
{
private SQLiteConnection connection;
public DataAccess()
{
var entity = DependencyService.Get<IEntity>();
connection = new SQLiteConnection(entity.Plataforma, System.IO.Path.Combine(entity.DirectorioBD, "Infraccions.db3"));
connection.CreateTable<Infraccion>();
}
public void InsertInfraccion(Infraccion infraccion)
{
connection.Insert(infraccion);
}
public void UpdateInfraccion(Infraccion infraccion)
{
connection.Update(infraccion);
}
public Infraccion GetInfraccion(int InfraccionID)
{
return connection.Table<Infraccion>().FirstOrDefault(c => c.InfraccionID == InfraccionID);
}
public List<Infraccion> GetInfraccions()
{
return connection.Table<Infraccion>().OrderBy(c => c.MotivoID).ToList();
}
public void DeleteInfraccion(Infraccion infraccion)
{
connection.Delete(infraccion);
}
public void Dispose()
{
connection.Dispose();
}
}
Should I create a table called Infraccions.db3 on my phone?
Thank you for your comments...
Are you saying that all new records have an ID of 0 and overwrite the existing record in the database?
If so, then this is how SQLite works - for int columns 0 is a valid value, so when the ID is 0 it will overwrite the record, instead of incrementing the value.
The correct way to use int primary keys is to define your primary key as a nullable int, that way the value for a new record is null, which will be updated to the next available id:
[PrimaryKey, AutoIncrement]
public int? ViolationID {get; set; }
Essentially change int to int?.
1) When entering a record in my DB, it takes the ID = 0, in my data
model use
You are using primary key and auto increment in your model that's means you are not able to enter 0 manually in the primary field and it takes automatically next value in this field.
2) How can I verify that these records are actually being entered?
You can get DB file path when you create your database and you can able to open and see that data.
(System.IO.Path.Combine(entity.DirectorioBD, "Infraccions.db3") )
There are many browser plugins to access the sqllite database.

How to store data owned by User?

I'm learning Google App Engine + Google Cloud Endpoints + Objectify and I'm trying to understand how to create REST API which will let each particular user to save his data in the cloud.
My current struggle is how to store Entity owned by the User (com.google.appengine.api.users.User)?
So far I have endpoint:
#ApiMethod(name = "saveBook")
public void saveBook(Book book, User user) throws OAuthRequestException, IOException {
if (user == null) {
throw new OAuthRequestException("User is not authorized");
}
ofy().save()
.entity(BookRecord.fromBook(user, book))
.now();
}
Entity (in this context let's assume that User wrote the book):
#Entity
public class BookRecord {
#Parent
private Key<User> user;
#Id
private String id;
#Index
private String name;
public static BookRecord fromBook(User user, Book book) {
return new BookRecord(
Key.create(user),
book.getId(),
book.getName()
);
}
public BookRecord() {
}
private BookRecord(Key<User> user, String id, String name, String author) {
this.user = user;
this.id = id;
this.name = name;
this.author = author;
}
}
Problem arises from User not being an Entity, so I can't really use this solution and use User as #Parent directly. What is the general solution to solve this problem and store data owned by User?
Create your own User entity, this is where you'll store custom information/preferences for your app (as I suggested here).
You'll be using getUserId() to tie it with the Google user, and from there on you're free to use it as needed.

[RuntimeException: No EntityManager bound to this thread. Try to annotate your action method with #play.db.jpa.Transactional]

this is the problem once i try to save data into db with sql statement insert.
my function is this:
public void save(){
JPA.em().persist(this);
}
and
public static Result registered() {
Form<User> requestform = form(User.class).bindFromRequest();
if(requestform.hasErrors()){
return badRequest("<p>fehlerhafte eingabe!</p>").as("text/html");
} else {
User user = requestform.get();
String fullname = user.fullname;
String email = user.email;
String password = user.password;
String username = user.username;
new User(username, password, fullname, email).save();
}
return redirect(controllers.routes.Application.index());
}
thanks for help
It is just like the debugging message says, you do not have an entity manager bound to your methods because they are not marked as transactions.
#play.db.jpa.Transactional
public static Result registered() {
Also, if you are using EBean, you could just extend Model for your User class, which comes with many handy built in functions for database use, see documentation here: http://www.playframework.org/documentation/2.0.1/JavaEbean

How do I query a single field in AppEngine using JDO

I've got a Product POJO that looks like.
#PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Product extends AbstractModel {
#Persistent
private String name;
#Persistent
private Key homePage;
#Persistent
private Boolean featured;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Key getHomePage() {
return homePage;
}
public void setHomePage(Key homePage) {
this.homePage = homePage;
}
public boolean isFeatured() {
return featured;
}
public void setFeatured(Boolean featured) {
this.featured = featured;
}
}
My DataStore is currently completely empty.
I'd like to retrieve all homePage keys where featured is true for the Product.
I'm trying
PersistenceManager persistenceManager = getPersistenceManager();
Query query = persistenceManager.newQuery("SELECT homePage FROM " + getModelClass());
query.setFilter("featured == true");
List<Key> productPageKeys = (List<Key>) query.execute();
However this is giving me a null pointer error. How should I be constructing this query?
Cheers,
Peter
To do a projection, you would do something like
Query q = pm.newQuery("SELECT myField FROM mydomain.MyClass WHERE featured == true");
List<String> results = (List<String>)q.execute();
where String is the type of my field. Any basic JDO documentation would define that.
Internally GAE/J will retrieve the Entity, and then in the post-processing before returning it to the user it is manipulated into the projection you require.
As Nick pointed out in the other reply, this gives no performance gain over doing it yourself ... but then the whole point of a standard persistence API is to shield you from such datastore-specifics of having to do such extraction; it's all provided out of the box.
Entities are stored as serialized blobs of data in the datastore, so it's not possible to retrieve and return a single field from an entity. You need to fetch the whole entity, and extract the field you care about yourself.

Resources